import numpy as np
import argparse
# import glob
import pathlib
import os
import webbrowser as web
from functools import partial
import vispy
import scipy.misc as misc
from tqdm import tqdm
# import yaml
import time
import sys
from mesh import write_ply, read_ply, output_3d_photo
from utils import get_MiDaS_samples, read_MiDaS_depth
import torch
import cv2
from skimage.transform import resize
import imageio
import copy
from networks import Inpaint_Color_Net, Inpaint_Depth_Net, Inpaint_Edge_Net
from MiDaS.run import run_depth
from MiDaS.monodepth_net import MonoDepthNet
import MiDaS.MiDaS_utils as MiDaS_utils
from bilateral_filtering import sparse_bilateral_filtering

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


# device = torch.device('cuda')
# precision = torch.float32
# loader = transforms.Compose([
#     transforms.ToTensor()])


# class MattingProgressBar(QWidget):
#     close_Signal = pyqtSignal(int)
#     def __init__(self):
#         super(MattingProgressBar,self).__init__()
#         self.setStyleSheet(
#             'QWidget{background-color:rgb(75,75,75);color:rgb(200,200,200)}')
#
#         self.setWindowTitle('生成Alpha')
#         self.setWindowFlags(Qt.WindowStaysOnTopHint)
#         self.setMinimumWidth(500)
#         self.mainLayout=QVBoxLayout()
#         self.mainLayout.setContentsMargins(15,12,15,15)
#         self.tip_layout =QHBoxLayout()
#         self.tip_layout.setAlignment(Qt.AlignCenter)
#         self.tip_label=QLabel("文件名：")
#         self.tip_name =QLabel('xxx')
#         self.tip_layout.addWidget(self.tip_label)
#         self.tip_layout.addWidget(self.tip_name)
#         self.frame_layout =QHBoxLayout()
#         self.frame_layout.setAlignment(Qt.AlignCenter)
#         self.all_frame_label = QLabel('总帧数: ')
#         self.all_frame = QLabel('0')
#         self.frame_layout.addWidget(self.all_frame_label)
#         self.frame_layout.addWidget(self.all_frame)
#         self.current_frame_layout =QHBoxLayout()
#         self.current_frame_layout.setAlignment(Qt.AlignCenter)
#         self.current_frame_label =QLabel('当前帧:')
#         self.current_frame = QLabel('0')
#         self.current_frame_layout.addWidget(self.current_frame_label)
#         self.current_frame_layout.addWidget(self.current_frame)
#         self.progress_layout=QHBoxLayout()
#         self.p=QProgressBar()
#
#
#         self.mainLayout.addLayout(self.tip_layout)
#         self.mainLayout.addLayout(self.frame_layout)
#         self.mainLayout.addLayout(self.current_frame_layout)
#         self.mainLayout.addWidget(self.p)
#         self.setLayout(self.mainLayout)
#
#     def setValue(self,value):
#         self.p.setValue(value)
#
#     def closeEvent(self, QCloseEvent):
#         self.close_Signal.emit(1)

#
# class MattingThread(QThread):
#     back_Signal =pyqtSignal(dict)
#     def __init__(self,data_info):
#         super(MattingThread,self).__init__()
#
#         self.model_path =data_info['model_path']
#         self.sample_type = data_info['sample_type']
#         self.model_type = data_info['model_type']
#         self.current_filename = data_info['filename'] #当前正在转化的文件名
#         self.type = data_info['type']
#         self.src_path = data_info['src_path']
#         self.bg_path = data_info['bg_path']
#         self.out_dir = data_info['out_dir']
#         self.running =False
#         self.count = 0   #当前执行帧数
#
#
#         self.model = MattingRefine(backbone=self.model_type,
#                               backbone_scale=0.25,
#                               refine_mode=self.sample_type)
#         self.model.load_state_dict(torch.load(self.model_path))
#         print('start 02')
#         self.model = self.model.eval().to(precision).to(device)
#         print('start 03')
#         self.fg_imgs,self.bg_imgs,self.all_frames = self.get_imgs()
#         print('start 04')
#
#         print('self.all_frames:',self.all_frames)
#
#
#     def get_imgs(self):
#         if self.type == 'video_video':
#             fg= VideoDataset(self.src_path)
#             bg= VideoDataset(self.bg_path)
#             all_frames = fg.frame_count
#         elif self.type in ['video_img','video_imgs']:
#             fg= VideoDataset(self.src_path)
#             bg = self.bg_path
#             all_frames = fg.frame_count
#         elif self.type == 'img_img':
#             fg= self.src_path
#             bg = self.bg_path
#             all_frames = 1
#         elif self.type == 'imgs_video':
#             fg= self.src_path
#             bg = VideoDataset(self.bg_path)
#             all_frames = len(self.src_path)
#         elif self.type == 'imgs_imgs':
#             fg= self.src_path
#             bg = self.bg_path
#             all_frames = len(fg)
#
#
#         return fg,bg,all_frames
#
#     def image2tensor(self,image_name):
#         image = Image.open(image_name).convert('RGB')
#         image = loader(image).unsqueeze(0)
#         return image.to(device, torch.float)
#
#     def pil2tensor(self,pil_img):
#         image = loader(pil_img).unsqueeze(0)
#         return image.to(device, torch.float)
#
#     def writer(self,img, path):
#         img = to_pil_image(img[0].cpu())
#         img.save(path)
#
#
#     def video_video(self,filename,model,fg_imgs,bg_imgs):
#         """
#         视频前景与视频背景
#         """
#         with torch.no_grad():
#             for i in range(fg_imgs.frame_count):
#                 if self.running:
#                     src_tensor= self.pil2tensor(fg_imgs[i])
#                     bg_tensor = self.pil2tensor(bg_imgs[i])
#                     pha, fgr = model(src_tensor, bg_tensor)[:2]
#                     out_dir = os.path.join(self.out_dir,filename)
#                     if not os.path.exists(out_dir):
#                         os.makedirs(out_dir)
#                     out_path = os.path.join(out_dir,'{}.{}.png'.format(self.model_type,'%04d' % (i+1)))
#                     self.writer(pha, out_path)
#                     self.count += 1
#                     print('{}完成'.format(i + 1))
#
#     def video_img(self,filename,model,fg_imgs,bg_path):
#         """
#         单视频前景与单背景图输出
#         """
#         bg_tensor = self.image2tensor(bg_path)
#         with torch.no_grad():
#             for i in range(fg_imgs.frame_count):
#                 if self.running:
#                     src_tensor= self.pil2tensor(fg_imgs[i])
#                     pha, fgr = model(src_tensor, bg_tensor)[:2]
#                     out_dir = os.path.join(self.out_dir,filename)
#                     if not os.path.exists(out_dir):
#                         os.makedirs(out_dir)
#                     out_path = os.path.join(out_dir,'{}.{}.png'.format(self.model_type,'%04d' % (i+1)))
#                     self.writer(pha, out_path)
#                     self.count += 1
#                     print('{}完成'.format(i + 1))
#
#     def video_imgs(self,filename,model,fg_imgs,bg_paths):
#         """
#         单视频前景与单背景序列输出
#         """
#
#         with torch.no_grad():
#             for i in range(fg_imgs.frame_count):
#                 print('self.running:',self.running)
#                 if self.running:
#                     src_tensor= self.pil2tensor(fg_imgs[i])
#                     bg_tensor =self.image2tensor(bg_paths[i])
#                     pha, fgr = model(src_tensor, bg_tensor)[:2]
#                     out_dir = os.path.join(self.out_dir,filename)
#                     if not os.path.exists(out_dir):
#                         os.makedirs(out_dir)
#                     out_path = os.path.join(out_dir,'{}.{}.png'.format(self.model_type,'%04d' % (i+1)))
#                     self.writer(pha, out_path)
#                     self.count += 1
#                     print('{}完成'.format(i + 1))
#
#     def img_img(self,filename,model,src_path,bg_path):
#         """
#         单图片前景与单图片背景输出
#         """
#         src_tensor = self.image2tensor(src_path)
#         bg_tensor = self.image2tensor(bg_path)
#         with torch.no_grad():
#             pha, fgr = model(src_tensor, bg_tensor)[:2]
#             out_dir = os.path.join(self.out_dir, filename)
#             if not os.path.exists(out_dir):
#                 os.makedirs(out_dir)
#             out_path = os.path.join(out_dir, '{}.png'.format(self.model_type))
#             self.writer(pha, out_path)
#             self.count += 1
#             print('完成')
#
#     def imgs_video(self,filename,model,src_paths,bg_imgs):
#         """
#         序列前景与单视频背景
#         """
#
#         with torch.no_grad():
#             for i in range(len(src_paths)):
#                 if self.running:
#                     src_tensor = self.image2tensor(src_paths[i])
#                     bg_tensor = self.pil2tensor(bg_imgs[i])
#                     pha, fgr = model(src_tensor, bg_tensor)[:2]
#                     out_dir = os.path.join(self.out_dir, filename)
#                     if not os.path.exists(out_dir):
#                         os.makedirs(out_dir)
#                     out_path = os.path.join(out_dir, '{}.{}.png'.format(self.model_type, '%04d' % (i+1)))
#                     self.writer(pha, out_path)
#                     self.count += 1
#                     print('{}完成'.format(i + 1))
#
#     def imgs_imgs(self,filename,model,src_paths,bg_paths):
#         """
#         序列前景与序列背景
#         """
#         with torch.no_grad():
#             for i in range(len(src_paths)):
#                 if self.running:
#                     src_tensor = self.image2tensor(src_paths[i])
#                     bg_tensor = self.image2tensor(bg_paths[i])
#                     pha, fgr = model(src_tensor, bg_tensor)[:2]
#                     out_dir = os.path.join(self.out_dir, filename)
#                     if not os.path.exists(out_dir):
#                         os.makedirs(out_dir)
#                     out_path = os.path.join(out_dir, '{}.{}.png'.format(self.model_type, i + 1))
#                     self.writer(pha, out_path)
#                     self.count += 1
#                     print('{}完成'.format(i + 1))
#
#
#     def run(self):
#         print('start')
#         print(self.model_type)
#         print(self.sample_type)
#
#         try:
#             eval('self.{}'.format(self.type))(self.current_filename,self.model,self.fg_imgs,self.bg_imgs)
#             print('start 04')
#         except Exception as run_ERR:
#             print('run_ERR:',str(run_ERR))
#
#


class PhotoInpainting(QWidget):

    def __init__(self):
        super(PhotoInpainting, self).__init__()

        self.config = {'depth_edge_model_ckpt': 'checkpoints/edge-model.pth',
                       'depth_feat_model_ckpt': 'checkpoints/depth-model.pth',
                       'rgb_feat_model_ckpt': 'checkpoints/color-model.pth',
                       'MiDaS_model_ckpt': 'MiDaS/model.pt',
                       'fps': 40,
                       'num_frames': 240,
                       'x_shift_range': [0.00, 0.00, -0.02, -0.02],
                       'y_shift_range': [0.00, 0.00, -0.02, -0.00],
                       'z_shift_range': [-0.05, -0.05, -0.07, -0.07],
                       'traj_types': ['double-straight-line', 'double-straight-line', 'circle', 'circle'],
                       'video_postfix': ['dolly-zoom-in', 'zoom-in', 'circle', 'swing'],
                       'specific': '',
                       'longer_side_len': 960,
                       'src_folder': 'image',
                       'depth_folder': 'depth',
                       'mesh_folder': 'mesh',
                       'video_folder': 'video',
                       'load_ply': False,
                       'save_ply': True,
                       'inference_video': True,
                       'gpu_ids': 0,
                       'offscreen_rendering': False,
                       'img_format': '.jpg',
                       'depth_format': '.npy',
                       'require_midas': True,
                       'depth_threshold': 0.04,
                       'ext_edge_threshold': 0.002,
                       'sparse_iter': 5,
                       'filter_size': [7, 7, 5, 5, 5],
                       'sigma_s': 4.0,
                       'sigma_r': 0.5,
                       'redundant_number': 12,
                       'background_thickness': 70,
                       'context_thickness': 140,
                       'background_thickness_2': 70,
                       'context_thickness_2': 70,
                       'discount_factor': 1.00,
                       'log_depth': True,
                       'largest_size': 512,
                       'depth_edge_dilate': 10,
                       'depth_edge_dilate_2': 5,
                       'extrapolate_border': True,
                       'extrapolation_thickness': 60,
                       'repeat_inpaint_edge': True,
                       'crop_border': [0.03, 0.03, 0.05, 0.03],
                       'anti_flickering': True
                       }

        icon = QIcon()
        cgai_icon = str(pathlib.Path('CGAI.png').resolve())
        icon.addPixmap(QPixmap(cgai_icon))

        project_dir = pathlib.Path().resolve()
        # model_dir = project_dir.joinpath('model')
        # print('model_dir:',model_dir)
        # self.mobilenetv2_model = str(model_dir.joinpath('pytorch_mobilenetv2.pth'))
        # self.resnet50_model = str(model_dir.joinpath('pytorch_resnet50.pth'))
        # self.resnet101_model = str(model_dir.joinpath('pytorch_resnet101.pth'))

        p = self.palette()
        p.setColor(QPalette.Base, QColor('#1C1C1C'))
        p.setColor(QPalette.Window, QColor('#393939'))
        p.setColor(QPalette.WindowText, QColor('#E8E8E8'))
        p.setColor(QPalette.Text, QColor('#1C1C1C'))

        self.setPalette(p)

        self.big_font = QFont('', 20, 65)
        self.mid_font = QFont('', 11, 75)

        self.link_btn_style = '''QPushButton{color:black}
                                  QPushButton:hover{color:#FF7F24}
                                  QPushButton{background-color:#CFCFCF}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:10px}
                                  QPushButton{padding:5px 1px}'''

        self.file_btn_style = '''QPushButton{color:black}
                                  QPushButton:hover{color:#FF7F24}
                                  QPushButton{background-color:#CFCFCF}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:5px 1px}'''

        self.export_btn_style = '''QPushButton{color:black}
                                  QPushButton:hover{color:#FF7F24}
                                  QPushButton{background-color:#CFCFCF}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:5px 1px}'''

        self.radio_btn_style = ''' QRadioButton:hover{color:#FF7F24}
                                   QRadioButton{color : #E8E8E8}
                                   QRadioButton{border:2px}
                                   QRadioButton{border-radius:10px}
                                   QRadioButton{padding:5px 1px}'''

        self.input_type = '图片'
        self.sample_type = 'sampling'
        self.model_type = 'mobilenetv2'

        self.setWindowIcon(icon)
        self.setWindowTitle('3D Photography')
        self.setMinimumHeight(500)
        self.setMaximumWidth(650)
        # self.setMaximumHeight(600)

        self.main_layout = QVBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setSpacing(18)

        self.cgai_layout = QHBoxLayout()
        self.cgai_layout.setAlignment(Qt.AlignLeft)
        self.cgai_icon = QLabel()
        cgai_pixmap = QPixmap(cgai_icon)
        scaled_pixmap = cgai_pixmap.scaled(80, 80, Qt.KeepAspectRatio)  #
        self.cgai_icon.setPixmap(scaled_pixmap)  # scale_pixmap
        self.cgai_label = QLabel('3D Photography 模型应用')
        self.cgai_label.setFont(self.big_font)
        self.cgai_layout.addWidget(self.cgai_icon)
        self.cgai_layout.addWidget(self.cgai_label)

        """
        需要的参数：
        fps : 帧数率
        num_frames : 总帧数 
        x_shift_range : [0.00, 0.00, -0.02, -0.02] 每种traj_type对应的起始x偏移
        y_shift_range : [0.00, 0.00, -0.02, -0.00] 每种traj_type对应的起始y偏移
        z_shift_range : [-0.05, -0.05, -0.07, -0.07] 每种traj_type对应的起始z偏移
        traj_types : ['double-straight-line', 'double-straight-line', 'circle', 'circle']  
                    镜头类型：double-straight-line,前后镜头
                             circle循环
        #video_postfix : ['dolly-zoom-in', 'zoom-in', 'circle', 'swing']  #视频类型名称
        longer_side_len: 960  宽高最长一方限制数，比如480x1080 那么会等比例缩放为 540 x 960,保持原尺寸 只需将原代码frac限制为1即可
        gpu_ids : 0  默认GPU索引
        depth_threshold: 0.04  深度阈值
        ext_edge_threshold: 0.002 边缘阈值
        sparse_iter: 5  稀疏迭代次数
        sigma_s: 4.0  双边滤波器 在坐标空间中过滤西格玛。较大的参数值意味着只要它们的颜色足够接近，更远的像素就会相互影响
        sigma_r: 0.5  双边滤波器 过滤西格玛的随机范围
        redundant_number: 12  冗余边最大数量
        background_thickness: 70  背景厚度
        context_thickness: 140   内容厚度
        background_thickness_2: 70 
        context_thickness_2: 70

        largest_size: 512 最大尺寸,尺寸归一用的
        depth_edge_dilate: 10  深度边缘拓展
        depth_edge_dilate_2: 5  深度边缘拓展

        extrapolation_thickness: 60  向外拓展厚度
        #repeat_inpaint_edge: True 
        crop_border: [0.03, 0.03, 0.05, 0.03]  裁剪边框

        """

        self.git_layout = QHBoxLayout()
        self.git_layout.setContentsMargins(0, 0, 0, 20)
        self.gitee_btn = QPushButton('Gitee 源码')
        self.gitee_btn.clicked.connect(self._open_gitee)
        self.gitee_btn.setStyleSheet(self.link_btn_style)
        self.github_btn = QPushButton('Github 原项目')
        self.github_btn.clicked.connect(self._open_github)
        self.github_btn.setStyleSheet(self.link_btn_style)
        self.baidu_btn = QPushButton('百度云:提取码CGAI')
        self.baidu_btn.clicked.connect(self._open_baidupan)
        self.baidu_btn.setStyleSheet(self.link_btn_style)
        self.help_btn = QPushButton('使用帮助')
        self.help_btn.clicked.connect(self._help)
        self.help_btn.setStyleSheet(self.link_btn_style)
        self.git_layout.addWidget(self.gitee_btn)
        self.git_layout.addWidget(self.github_btn)
        self.git_layout.addWidget(self.baidu_btn)
        self.git_layout.addWidget(self.help_btn)

        self.scroll_area =QScrollArea()
        # self.scroll_area.setStyleSheet('QScrollBar{width:5px}')
        self.parm_widegt=QWidget()
        self.parm_widegt.setPalette(p)
        self.parm_widegt.setMinimumHeight(800)
        self.parm_widegt.setFixedWidth(700)
        self.parm_layout =QVBoxLayout()
        self.parm_layout.setAlignment(Qt.AlignTop)
        self.parm_widegt.setLayout(self.parm_layout)
        self.scroll_area.setWidget(self.parm_widegt)


        float_rex = QRegExp("[0-9\.-]+$")
        int_rex = QRegExp("[0-9]+$")
        self.float_rv = QRegExpValidator(float_rex, self)
        self.int_rv = QRegExpValidator(int_rex, self)

        self.main_parm_layout = QHBoxLayout()
        # self.main_parm_layout.setAlignment(Qt.AlignCenter)
        self.main_parm_label =QLabel('Base Parameters')
        self.main_parm_label.setFont(self.mid_font)
        self.main_parm_label.setStyleSheet('color: #89baeb')
        self.main_parm_layout.addWidget(self.main_parm_label)

        self.fps_layout = QHBoxLayout()
        self.fps_layout.setContentsMargins(0,0,400,0)
        self.fps_layout.setSpacing(55)
        self.fps_layout.setAlignment(Qt.AlignLeft)
        self.fps_label = QLabel('fps:')
        self.fps_label.setToolTip('帧数率')
        self.fps_label.setFont(self.mid_font)
        self.fps_eidt = QLineEdit()

        self.fps_eidt.setValidator(self.int_rv)
        self.fps_eidt.setText('30')
        self.fps_eidt.setFixedWidth(50)
        self.fps_layout.addWidget(self.fps_label)
        self.fps_layout.addWidget(self.fps_eidt)

        self.num_frames_layout =QHBoxLayout()
        self.num_frames_layout.setContentsMargins(0,0,400,0)
        self.num_frames_layout.setSpacing(55)
        self.num_frames_layout.setAlignment(Qt.AlignLeft)
        self.num_frames_label = QLabel('num_frames:')
        self.num_frames_label.setToolTip('总帧数')
        self.num_frames_label.setFont(self.mid_font)
        self.num_frames_eidt = QLineEdit()
        self.num_frames_eidt.setValidator(self.int_rv)
        self.num_frames_eidt.setText('180')
        self.num_frames_eidt.setFixedWidth(50)
        self.num_frames_layout.addWidget(self.num_frames_label)
        self.num_frames_layout.addWidget(self.num_frames_eidt)

        self.longer_side_len_layout =QHBoxLayout()
        self.longer_side_len_layout.setContentsMargins(0,0,270,0)
        self.longer_side_len_layout.setSpacing(10)
        self.longer_side_len_layout.setAlignment(Qt.AlignLeft)
        self.longer_side_len_label = QLabel('longer_side_len:')
        self.longer_side_len_label.setToolTip('宽高最长一方限制数，比如480x1080 那么会等比例缩放为 540 x 960')
        self.longer_side_len_label.setFont(self.mid_font)
        self.longer_side_len_eidt = QLineEdit()
        self.longer_side_len_eidt.setValidator(self.int_rv)
        self.longer_side_len_eidt.setText('960')
        self.longer_side_len_eidt.setFixedWidth(50)
        self.keep_len_check = QCheckBox('保持原图大小')
        self.keep_len_check.clicked.connect(self._keep_len)
        self.longer_side_len_layout.addWidget(self.longer_side_len_label)
        self.longer_side_len_layout.addWidget(self.longer_side_len_eidt)
        self.longer_side_len_layout.addWidget(self.keep_len_check)


        self.save_ply_layout =QHBoxLayout()
        self.save_ply_layout.setContentsMargins(0,0,400,0)
        self.save_ply_layout.setSpacing(55)
        self.save_ply_layout.setAlignment(Qt.AlignLeft)
        self.save_ply_label = QLabel('save_ply:')
        self.save_ply_label.setToolTip('是否保持3D模型')
        self.save_ply_label.setFont(self.mid_font)
        self.save_ply_check = QCheckBox('保存3D模型')
        self.save_ply_check.setChecked(False)
        self.save_ply_layout.addWidget(self.save_ply_label)
        self.save_ply_layout.addWidget(self.save_ply_check)


        self.gpu_ids_layout =QHBoxLayout()
        self.gpu_ids_layout.setContentsMargins(0,0,400,20)
        self.gpu_ids_layout.setSpacing(55)
        self.gpu_ids_layout.setAlignment(Qt.AlignLeft)
        self.gpu_ids_label = QLabel('gpu_ids:')
        self.gpu_ids_label.setToolTip('GPU索引,0为当前默认第一块GPU')
        self.gpu_ids_label.setFont(self.mid_font)
        self.gpu_ids_eidt = QLineEdit()
        self.gpu_ids_eidt.setValidator(self.int_rv)
        self.gpu_ids_eidt.setText('0')
        self.gpu_ids_eidt.setFixedWidth(50)
        self.gpu_ids_layout.addWidget(self.gpu_ids_label)
        self.gpu_ids_layout.addWidget(self.gpu_ids_eidt)

        self.advanced_parm_layout = QHBoxLayout()
        # self.advanced_parm_layout.setAlignment(Qt.AlignLeft)
        self.advanced_parm_label =QLabel('Advanced Parameters')
        self.advanced_parm_label.setFont(self.mid_font)
        self.advanced_parm_label.setStyleSheet('color: #9cbbfc')
        self.advanced_parm_layout.addWidget(self.advanced_parm_label)


        self.traj_types_layout =QHBoxLayout()
        self.traj_types_layout.setAlignment(Qt.AlignLeft)
        self.traj_types_layout.setContentsMargins(0,0,0,0)
        self.traj_types_label =QLabel('traj_types:')
        self.traj_types_label.setFont(self.mid_font)
        self.traj_types_label.setToolTip('镜头运动轨迹:')
        self.traj_types_0 = QLabel('double-straight-line')
        self.traj_types_0.setToolTip('双直线')
        self.traj_types_1 = QLabel('double-straight-line')
        self.traj_types_1.setToolTip('双直线')
        self.traj_types_2 = QLabel('circle')
        self.traj_types_2.setToolTip('循环')
        self.traj_types_3 = QLabel('circle')
        self.traj_types_3.setToolTip('循环')
        self.traj_types_layout.addWidget(self.traj_types_label)
        self.traj_types_layout.addWidget(self.traj_types_0)
        self.traj_types_layout.addWidget(self.traj_types_1)
        self.traj_types_layout.addWidget(self.traj_types_2)
        self.traj_types_layout.addWidget(self.traj_types_3)

        self.x_shift_range_layout= QHBoxLayout()
        self.x_shift_range_layout.setAlignment(Qt.AlignLeft)
        self.x_shift_range_layout.setContentsMargins(0, 0, 230, 0)
        self.x_shift_range_label =QLabel('x_shift_range:')
        self.x_shift_range_label.setToolTip('每种镜头运动对应的起始x偏移')
        self.x_shift_range_label.setFont(self.mid_font)
        self.x_shift_range_0 = QLineEdit()
        self.x_shift_range_0.setValidator(self.float_rv)
        self.x_shift_range_0.setFixedWidth(50)
        self.x_shift_range_0.setText('0.00')
        self.x_shift_range_1 = QLineEdit()
        self.x_shift_range_1.setFixedWidth(50)
        self.x_shift_range_1.setValidator(self.float_rv)
        self.x_shift_range_1.setText('0.00')
        self.x_shift_range_2 = QLineEdit()
        self.x_shift_range_2.setFixedWidth(50)
        self.x_shift_range_2.setValidator(self.float_rv)
        self.x_shift_range_2.setText('-0.02')
        self.x_shift_range_3 = QLineEdit()
        self.x_shift_range_3.setFixedWidth(50)
        self.x_shift_range_3.setValidator(self.float_rv)
        self.x_shift_range_3.setText('-0.02')
        self.x_shift_range_layout.addWidget(self.x_shift_range_label)
        self.x_shift_range_layout.addWidget(self.x_shift_range_0)
        self.x_shift_range_layout.addWidget(self.x_shift_range_1)
        self.x_shift_range_layout.addWidget(self.x_shift_range_2)
        self.x_shift_range_layout.addWidget(self.x_shift_range_3)

        self.y_shift_range_layout= QHBoxLayout()
        self.y_shift_range_layout.setAlignment(Qt.AlignLeft)
        self.y_shift_range_layout.setContentsMargins(0, 0, 230, 0)
        self.y_shift_range_label =QLabel('y_shift_range:')
        self.y_shift_range_label.setToolTip('每种镜头运动对应的起始y偏移')
        self.y_shift_range_label.setFont(self.mid_font)
        self.y_shift_range_0 = QLineEdit()
        self.y_shift_range_0.setValidator(self.float_rv)
        self.y_shift_range_0.setFixedWidth(50)
        self.y_shift_range_0.setText('0.00')
        self.y_shift_range_1 = QLineEdit()
        self.y_shift_range_1.setFixedWidth(50)
        self.y_shift_range_1.setValidator(self.float_rv)
        self.y_shift_range_1.setText('0.00')
        self.y_shift_range_2 = QLineEdit()
        self.y_shift_range_2.setFixedWidth(50)
        self.y_shift_range_2.setValidator(self.float_rv)
        self.y_shift_range_2.setText('-0.02')
        self.y_shift_range_3 = QLineEdit()
        self.y_shift_range_3.setFixedWidth(50)
        self.y_shift_range_3.setValidator(self.float_rv)
        self.y_shift_range_3.setText('0.00')
        self.y_shift_range_layout.addWidget(self.y_shift_range_label)
        self.y_shift_range_layout.addWidget(self.y_shift_range_0)
        self.y_shift_range_layout.addWidget(self.y_shift_range_1)
        self.y_shift_range_layout.addWidget(self.y_shift_range_2)
        self.y_shift_range_layout.addWidget(self.y_shift_range_3)

        self.z_shift_range_layout= QHBoxLayout()
        self.z_shift_range_layout.setAlignment(Qt.AlignLeft)
        self.z_shift_range_layout.setContentsMargins(0, 0, 230, 0)
        self.z_shift_range_label =QLabel('z_shift_range:')
        self.z_shift_range_label.setToolTip('每种镜头运动对应的起始z偏移')
        self.z_shift_range_label.setFont(self.mid_font)
        self.z_shift_range_0 = QLineEdit()
        self.z_shift_range_0.setValidator(self.float_rv)
        self.z_shift_range_0.setFixedWidth(50)
        self.z_shift_range_0.setText('-0.05')
        self.z_shift_range_1 = QLineEdit()
        self.z_shift_range_1.setFixedWidth(50)
        self.z_shift_range_1.setValidator(self.float_rv)
        self.z_shift_range_1.setText('-0.05')
        self.z_shift_range_2 = QLineEdit()
        self.z_shift_range_2.setFixedWidth(50)
        self.z_shift_range_2.setValidator(self.float_rv)
        self.z_shift_range_2.setText('-0.07')
        self.z_shift_range_3 = QLineEdit()
        self.z_shift_range_3.setFixedWidth(50)
        self.z_shift_range_3.setValidator(self.float_rv)
        self.z_shift_range_3.setText('-0.07')
        self.z_shift_range_layout.addWidget(self.z_shift_range_label)
        self.z_shift_range_layout.addWidget(self.z_shift_range_0)
        self.z_shift_range_layout.addWidget(self.z_shift_range_1)
        self.z_shift_range_layout.addWidget(self.z_shift_range_2)
        self.z_shift_range_layout.addWidget(self.z_shift_range_3)





        self.depth_threshold_layout = QHBoxLayout()
        self.depth_threshold_layout.setContentsMargins(0,0,400,0)
        self.depth_threshold_layout.setSpacing(15)
        self.depth_threshold_layout.setAlignment(Qt.AlignLeft)
        self.depth_threshold_label = QLabel('depth_threshold:')
        self.depth_threshold_label.setToolTip('深度阈值')
        self.depth_threshold_label.setFont(self.mid_font)
        self.depth_threshold_eidt = QLineEdit()
        self.depth_threshold_eidt.setValidator(self.float_rv)
        self.depth_threshold_eidt.setText('0.04')
        self.depth_threshold_eidt.setFixedWidth(50)
        self.depth_threshold_layout.addWidget(self.depth_threshold_label)
        self.depth_threshold_layout.addWidget(self.depth_threshold_eidt)

        self.ext_edge_threshold_layout =QHBoxLayout()
        self.ext_edge_threshold_layout.setContentsMargins(0,0,330,0)
        self.ext_edge_threshold_layout.setSpacing(55)
        self.ext_edge_threshold_layout.setAlignment(Qt.AlignLeft)
        self.ext_edge_threshold_label = QLabel('ext_edge_threshold:')
        self.ext_edge_threshold_label.setToolTip('边缘阈值')
        self.ext_edge_threshold_label.setFont(self.mid_font)
        self.ext_edge_threshold_eidt = QLineEdit()
        self.ext_edge_threshold_eidt.setValidator(self.float_rv)
        self.ext_edge_threshold_eidt.setText('0.002')
        self.ext_edge_threshold_eidt.setFixedWidth(50)
        self.ext_edge_threshold_layout.addWidget(self.ext_edge_threshold_label)
        self.ext_edge_threshold_layout.addWidget(self.ext_edge_threshold_eidt)

        self.sparse_iter_layout =QHBoxLayout()
        self.sparse_iter_layout.setContentsMargins(0,0,330,0)
        self.sparse_iter_layout.setSpacing(55)
        self.sparse_iter_layout.setAlignment(Qt.AlignLeft)
        self.sparse_iter_label = QLabel('sparse_iter:')
        self.sparse_iter_label.setToolTip('稀疏迭代次数')
        self.sparse_iter_label.setFont(self.mid_font)
        self.sparse_iter_eidt = QLineEdit()
        self.sparse_iter_eidt.setValidator(self.int_rv)
        self.sparse_iter_eidt.setText('5')
        self.sparse_iter_eidt.setFixedWidth(50)
        self.sparse_iter_layout.addWidget(self.sparse_iter_label)
        self.sparse_iter_layout.addWidget(self.sparse_iter_eidt)

        self.sigma_s_layout =QHBoxLayout()
        self.sigma_s_layout.setContentsMargins(0,0,330,0)
        self.sigma_s_layout.setSpacing(55)
        self.sigma_s_layout.setAlignment(Qt.AlignLeft)
        self.sigma_s_label = QLabel('sigma_s:')
        self.sigma_s_label.setToolTip('双边滤波器 在坐标空间中过滤西格玛。较大的参数值意味着只要它们的颜色足够接近，更远的像素就会相互影响')
        self.sigma_s_label.setFont(self.mid_font)
        self.sigma_s_eidt = QLineEdit()
        self.sigma_s_eidt.setValidator(self.float_rv)
        self.sigma_s_eidt.setText('4.0')
        self.sigma_s_eidt.setFixedWidth(50)
        self.sigma_s_layout.addWidget(self.sigma_s_label)
        self.sigma_s_layout.addWidget(self.sigma_s_eidt)

        self.sigma_r_layout =QHBoxLayout()
        self.sigma_r_layout.setContentsMargins(0,0,330,0)
        self.sigma_r_layout.setSpacing(55)
        self.sigma_r_layout.setAlignment(Qt.AlignLeft)
        self.sigma_r_label = QLabel('sigma_r:')
        self.sigma_r_label.setToolTip('双边滤波器 过滤西格玛的随机范围')
        self.sigma_r_label.setFont(self.mid_font)
        self.sigma_r_eidt = QLineEdit()
        self.sigma_r_eidt.setValidator(self.float_rv)
        self.sigma_r_eidt.setText('0.5')
        self.sigma_r_eidt.setFixedWidth(50)
        self.sigma_r_layout.addWidget(self.sigma_r_label)
        self.sigma_r_layout.addWidget(self.sigma_r_eidt)

        self.redundant_number_layout =QHBoxLayout()
        self.redundant_number_layout.setContentsMargins(0,0,330,0)
        self.redundant_number_layout.setSpacing(10)
        self.redundant_number_layout.setAlignment(Qt.AlignLeft)
        self.redundant_number_label = QLabel('redundant_number_layout:')
        self.redundant_number_label.setToolTip('冗余边最大数量')
        self.redundant_number_label.setFont(self.mid_font)
        self.redundant_number_eidt = QLineEdit()
        self.redundant_number_eidt.setValidator(self.int_rv)
        self.redundant_number_eidt.setText('12')
        self.redundant_number_eidt.setFixedWidth(50)
        self.redundant_number_layout.addWidget(self.redundant_number_label)
        self.redundant_number_layout.addWidget(self.redundant_number_eidt)

        self.background_thickness_layout = QHBoxLayout()
        self.background_thickness_layout.setContentsMargins(0,0,330,0)
        self.background_thickness_layout.setSpacing(10)
        self.background_thickness_layout.setAlignment(Qt.AlignLeft)
        self.background_thickness_label = QLabel('background_thickness:')
        self.background_thickness_label.setToolTip('背景厚度')
        self.background_thickness_label.setFont(self.mid_font)
        self.background_thickness_eidt = QLineEdit()
        self.background_thickness_eidt.setValidator(self.int_rv)
        self.background_thickness_eidt.setText('70')
        self.background_thickness_eidt.setFixedWidth(50)
        self.background_thickness_layout.addWidget(self.background_thickness_label)
        self.background_thickness_layout.addWidget(self.background_thickness_eidt)

        self.background_thickness2_layout = QHBoxLayout()
        self.background_thickness2_layout.setContentsMargins(0,0,330,0)
        self.background_thickness2_layout.setSpacing(10)
        self.background_thickness2_layout.setAlignment(Qt.AlignLeft)
        self.background_thickness2_label = QLabel('background_thickness2:')
        self.background_thickness2_label.setToolTip('背景厚度2')
        self.background_thickness2_label.setFont(self.mid_font)
        self.background_thickness2_eidt = QLineEdit()
        self.background_thickness2_eidt.setValidator(self.int_rv)
        self.background_thickness2_eidt.setText('70')
        self.background_thickness2_eidt.setFixedWidth(50)
        self.background_thickness2_layout.addWidget(self.background_thickness2_label)
        self.background_thickness2_layout.addWidget(self.background_thickness2_eidt)

        self.context_thickness_layout =QHBoxLayout()
        self.context_thickness_layout.setContentsMargins(0,0,330,0)
        self.context_thickness_layout.setSpacing(10)
        self.context_thickness_layout.setAlignment(Qt.AlignLeft)
        self.context_thickness_label = QLabel('context_thickness:')
        self.context_thickness_label.setToolTip('上下文厚度')
        self.context_thickness_label.setFont(self.mid_font)
        self.context_thickness_eidt = QLineEdit()
        self.context_thickness_eidt.setValidator(self.int_rv)
        self.context_thickness_eidt.setText('140')
        self.context_thickness_eidt.setFixedWidth(50)
        self.context_thickness_layout.addWidget(self.context_thickness_label)
        self.context_thickness_layout.addWidget(self.context_thickness_eidt)

        self.context_thickness2_layout =QHBoxLayout()
        self.context_thickness2_layout.setContentsMargins(0,0,330,0)
        self.context_thickness2_layout.setSpacing(10)
        self.context_thickness2_layout.setAlignment(Qt.AlignLeft)
        self.context_thickness2_label = QLabel('context_thickness2:')
        self.context_thickness2_label.setToolTip('上下文厚度2')
        self.context_thickness2_label.setFont(self.mid_font)
        self.context_thickness2_eidt = QLineEdit()
        self.context_thickness2_eidt.setValidator(self.int_rv)
        self.context_thickness2_eidt.setText('70')
        self.context_thickness2_eidt.setFixedWidth(50)
        self.context_thickness2_layout.addWidget(self.context_thickness2_label)
        self.context_thickness2_layout.addWidget(self.context_thickness2_eidt)

        self.largest_size_layout =QHBoxLayout()
        self.largest_size_layout.setContentsMargins(0,0,330,0)
        self.largest_size_layout.setSpacing(10)
        self.largest_size_layout.setAlignment(Qt.AlignLeft)
        self.largest_size_label = QLabel('largest_size:')
        self.largest_size_label.setToolTip('最大尺寸,尺寸归一用的')
        self.largest_size_label.setFont(self.mid_font)
        self.largest_size_eidt = QLineEdit()
        self.largest_size_eidt.setValidator(self.int_rv)
        self.largest_size_eidt.setText('512')
        self.largest_size_eidt.setFixedWidth(50)
        self.largest_size_layout.addWidget(self.largest_size_label)
        self.largest_size_layout.addWidget(self.largest_size_eidt)

        self.depth_edge_dilate_layout =QHBoxLayout()
        self.depth_edge_dilate_layout.setContentsMargins(0,0,330,0)
        self.depth_edge_dilate_layout.setSpacing(10)
        self.depth_edge_dilate_layout.setAlignment(Qt.AlignLeft)
        self.depth_edge_dilate_label = QLabel('depth_edge_dilate:')
        self.depth_edge_dilate_label.setToolTip('深度边缘拓展')
        self.depth_edge_dilate_label.setFont(self.mid_font)
        self.depth_edge_dilate_eidt = QLineEdit()
        self.depth_edge_dilate_eidt.setValidator(self.int_rv)
        self.depth_edge_dilate_eidt.setText('10')
        self.depth_edge_dilate_eidt.setFixedWidth(50)
        self.depth_edge_dilate_layout.addWidget(self.depth_edge_dilate_label)
        self.depth_edge_dilate_layout.addWidget(self.depth_edge_dilate_eidt)

        self.depth_edge_dilate2_layout = QHBoxLayout()
        self.depth_edge_dilate2_layout.setContentsMargins(0, 0, 330, 0)
        self.depth_edge_dilate2_layout.setSpacing(10)
        self.depth_edge_dilate2_layout.setAlignment(Qt.AlignLeft)
        self.depth_edge_dilate2_label = QLabel('depth_edge_dilate2:')
        self.depth_edge_dilate2_label.setToolTip('深度边缘拓展2')
        self.depth_edge_dilate2_label.setFont(self.mid_font)
        self.depth_edge_dilate2_eidt = QLineEdit()
        self.depth_edge_dilate2_eidt.setValidator(self.int_rv)
        self.depth_edge_dilate2_eidt.setText('5')
        self.depth_edge_dilate2_eidt.setFixedWidth(50)
        self.depth_edge_dilate2_layout.addWidget(self.depth_edge_dilate2_label)
        self.depth_edge_dilate2_layout.addWidget(self.depth_edge_dilate2_eidt)

        self.extrapolation_thickness_layout = QHBoxLayout()
        self.extrapolation_thickness_layout.setContentsMargins(0, 0, 330, 0)
        self.extrapolation_thickness_layout.setSpacing(10)
        self.extrapolation_thickness_layout.setAlignment(Qt.AlignLeft)
        self.extrapolation_thickness_label = QLabel('extrapolation_thickness:')
        self.extrapolation_thickness_label.setToolTip('向外拓展厚度')
        self.extrapolation_thickness_label.setFont(self.mid_font)
        self.extrapolation_thickness_eidt = QLineEdit()
        self.extrapolation_thickness_eidt.setValidator(self.int_rv)
        self.extrapolation_thickness_eidt.setText('60')
        self.extrapolation_thickness_eidt.setFixedWidth(50)
        self.extrapolation_thickness_layout.addWidget(self.extrapolation_thickness_label)
        self.extrapolation_thickness_layout.addWidget(self.extrapolation_thickness_eidt)

        self.crop_border_layout = QHBoxLayout()
        self.crop_border_layout.setContentsMargins(0, 0, 230, 0)
        self.crop_border_layout.setAlignment(Qt.AlignLeft)
        self.crop_border_label = QLabel('crop_border:')
        self.crop_border_label.setToolTip('裁剪边框')
        self.crop_border_label.setFont(self.mid_font)
        self.crop_border_0 = QLineEdit()
        self.crop_border_0.setValidator(self.float_rv)
        self.crop_border_0.setFixedWidth(50)
        self.crop_border_0.setText('0.03')
        self.crop_border_1 = QLineEdit()
        self.crop_border_1.setFixedWidth(50)
        self.crop_border_1.setValidator(self.float_rv)
        self.crop_border_1.setText('0.03')
        self.crop_border_2 = QLineEdit()
        self.crop_border_2.setFixedWidth(50)
        self.crop_border_2.setValidator(self.float_rv)
        self.crop_border_2.setText('0.05')
        self.crop_border_3 = QLineEdit()
        self.crop_border_3.setFixedWidth(50)
        self.crop_border_3.setValidator(self.float_rv)
        self.crop_border_3.setText('0.03')
        self.crop_border_layout.addWidget(self.crop_border_label)
        self.crop_border_layout.addWidget(self.crop_border_0)
        self.crop_border_layout.addWidget(self.crop_border_1)
        self.crop_border_layout.addWidget(self.crop_border_2)
        self.crop_border_layout.addWidget(self.crop_border_3)


        self.parm_layout.addLayout(self.main_parm_layout)
        self.parm_layout.addLayout(self.fps_layout)
        self.parm_layout.addLayout(self.num_frames_layout)
        self.parm_layout.addLayout(self.longer_side_len_layout)
        self.parm_layout.addLayout(self.save_ply_layout)
        self.parm_layout.addLayout(self.gpu_ids_layout)
        self.parm_layout.addLayout(self.advanced_parm_layout)
        self.parm_layout.addLayout(self.traj_types_layout)
        self.parm_layout.addLayout(self.x_shift_range_layout)
        self.parm_layout.addLayout(self.y_shift_range_layout)
        self.parm_layout.addLayout(self.z_shift_range_layout)

        self.parm_layout.addLayout(self.depth_threshold_layout)
        self.parm_layout.addLayout(self.ext_edge_threshold_layout)
        self.parm_layout.addLayout(self.sparse_iter_layout)
        self.parm_layout.addLayout(self.sigma_s_layout)
        self.parm_layout.addLayout(self.sigma_r_layout)
        self.parm_layout.addLayout(self.redundant_number_layout)
        self.parm_layout.addLayout(self.background_thickness_layout)
        self.parm_layout.addLayout(self.background_thickness2_layout)
        self.parm_layout.addLayout(self.context_thickness_layout)
        self.parm_layout.addLayout(self.context_thickness2_layout)
        self.parm_layout.addLayout(self.largest_size_layout)
        self.parm_layout.addLayout(self.depth_edge_dilate_layout)
        self.parm_layout.addLayout(self.depth_edge_dilate2_layout)
        self.parm_layout.addLayout(self.extrapolation_thickness_layout)
        self.parm_layout.addLayout(self.crop_border_layout)


        self.src_layout = QHBoxLayout()
        self.src_layout.setContentsMargins(0, 25, 0, 0)
        self.src_label = QLabel('图片目录 :')
        self.src_label.setFont(self.mid_font)
        self.src_edit = QLineEdit()
        self.src_btn = QPushButton('··')
        self.src_btn.setStyleSheet(self.file_btn_style)
        self.src_btn.clicked.connect(self._select_src)
        self.open_src_btn = QPushButton('👆')
        self.open_src_btn.setStyleSheet(self.file_btn_style)
        self.open_src_btn.clicked.connect(self._open_src)
        self.src_layout.addWidget(self.src_label)
        self.src_layout.addWidget(self.src_edit)
        self.src_layout.addWidget(self.src_btn)
        self.src_layout.addWidget(self.open_src_btn)

        self.export_layout = QHBoxLayout()
        self.export_label = QLabel('输出目录:')
        self.export_label.setFont(self.mid_font)
        self.export_edit = QLineEdit()
        self.export_btn = QPushButton('··')
        self.export_btn.setStyleSheet(self.file_btn_style)
        self.export_btn.clicked.connect(self._export_dir)
        self.open_export_btn = QPushButton('👆')
        self.open_export_btn.setStyleSheet(self.file_btn_style)
        self.open_export_btn.clicked.connect(self._open_export)
        self.export_layout.addWidget(self.export_label)
        self.export_layout.addWidget(self.export_edit)
        self.export_layout.addWidget(self.export_btn)
        self.export_layout.addWidget(self.open_export_btn)

        self.btn_layout = QHBoxLayout()
        self.btn_layout.setContentsMargins(0, 15, 0, 20)
        self.btn = QPushButton('生成3D视频')
        self.btn.setMaximumWidth(100)
        self.btn.setStyleSheet(self.export_btn_style)
        self.btn.clicked.connect(self._create)
        self.btn_layout.addWidget(self.btn)

        self.command_text = QTextBrowser()

        self.command_text.setTextColor(QColor('#E8E8E8'))
        self.command_text.append('CGAI即时演绎,让你所想即所有')
        self.command_text.setMinimumHeight(50)




        self.main_layout.addLayout(self.cgai_layout)
        self.main_layout.addLayout(self.git_layout)
        # self.main_layout.addWidget(self.type_frame)
        # self.main_layout.addWidget(self.sample_frame)
        # self.main_layout.addWidget(self.model_frame)
        # self.main_layout.addLayout(self.parm_layout)
        self.main_layout.addWidget(self.scroll_area)

        self.main_layout.addLayout(self.src_layout)
        # self.main_layout.addLayout(self.bg_layout)
        self.main_layout.addLayout(self.export_layout)
        self.main_layout.addLayout(self.btn_layout)
        self.main_layout.addWidget(self.command_text)

        self.setLayout(self.main_layout)

        # self.timer = QBasicTimer()

        # self.prog = MattingProgressBar()
        # self.prog.close_Signal.connect(self._close_prog)

    def _keep_len(self,stauts):
        if stauts:
            self.longer_side_len_eidt.setDisabled(True)
        else:
            self.longer_side_len_eidt.setDisabled(False)

    def update_parms(self):
        print('update_parms start')
        fps = int(self.fps_eidt.text())
        num_frame = int(self.num_frames_eidt.text())
        x_shift_range = [float(self.x_shift_range_0.text()),float(self.x_shift_range_1.text()),
                         float(self.x_shift_range_2.text()),float(self.x_shift_range_3.text())]

        y_shift_range = [float(self.y_shift_range_0.text()),float(self.y_shift_range_1.text()),
                         float(self.y_shift_range_2.text()),float(self.y_shift_range_3.text())]
        z_shift_range = [float(self.z_shift_range_0.text()),float(self.z_shift_range_1.text()),
                         float(self.z_shift_range_2.text()),float(self.z_shift_range_3.text())]
        # print('update_parms 001')
        longer_side_len = int(self.longer_side_len_eidt.text())
        save_ply = self.save_ply_check.isChecked()
        gpu_ids = int(self.gpu_ids_eidt.text())
        depth_threshold = float(self.depth_threshold_eidt.text())
        ext_edge_threshold = float(self.ext_edge_threshold_eidt.text())
        sparse_iter = int(self.sparse_iter_eidt.text())
        sigma_s = float(self.sigma_s_eidt.text())
        sigma_r = float(self.sigma_r_eidt.text())
        # print('update_parms 002')
        redundant_number = int(self.redundant_number_eidt.text())
        background_thickness = int(self.background_thickness_eidt.text())
        background_thickness_2 = int(self.background_thickness2_eidt.text())
        context_thickness = int(self.context_thickness_eidt.text())
        context_thickness_2 = int(self.context_thickness2_eidt.text())
        largest_size = int(self.largest_size_eidt.text())
        depth_edge_dilate = int(self.depth_edge_dilate_eidt.text())
        depth_edge_dilate_2 = int(self.depth_edge_dilate2_eidt.text())
        extrapolation_thickness = int(self.extrapolation_thickness_eidt.text())
        crop_border = [float(self.crop_border_0.text()),float(self.crop_border_1.text()),
                         float(self.crop_border_2.text()),float(self.crop_border_3.text())]
        # print('update_parms 003')
        parms = {'fps':fps,'num_frame':num_frame,'x_shift_range':x_shift_range,
                 'y_shift_range':y_shift_range,'z_shift_range':z_shift_range,'longer_side_len':longer_side_len,
                 'save_ply':save_ply,'gpu_ids':gpu_ids,'depth_threshold':depth_threshold,
                 'ext_edge_threshold':ext_edge_threshold,'sparse_iter':sparse_iter,'sigma_s':sigma_s,
                 'sigma_r':sigma_r,'redundant_number':redundant_number,'background_thickness':background_thickness,
                 'background_thickness_2':background_thickness_2,'context_thickness':context_thickness,'context_thickness_2':context_thickness_2,
                 'largest_size':largest_size,'depth_edge_dilate':depth_edge_dilate,'depth_edge_dilate_2':depth_edge_dilate_2,
                 'extrapolation_thickness':extrapolation_thickness,'crop_border':crop_border }

        self.config.update(parms)
        # import pprint
        # pprint.pprint(self.config)




    def _select_src(self):
        dir_path = QFileDialog.getExistingDirectory(self, '选择文件夹')
        # print('dir_path:',dir_path)
        if dir_path:
            self.src_edit.setText(dir_path)

    def _open_src(self):
        os.startfile(self.src_edit.text())

    def _select_bg(self):
        dir_path = QFileDialog.getExistingDirectory(self, '选择文件夹')
        if dir_path:
            self.bg_edit.setText(dir_path)


    def _export_dir(self):
        dir_path = QFileDialog.getExistingDirectory(self, '选择文件夹')
        if dir_path:
            self.export_edit.setText(dir_path)

    def _open_export(self):
        os.startfile(self.export_edit.text())

    def _open_gitee(self):
        web.open(r'https://gitee.com/cgai/mz_3d_photo_inpainting')

    def _open_github(self):
        web.open(r'https://github.com/vt-vl-lab/3d-photo-inpainting')

    def _open_baidupan(self):
        web.open(r'https://pan.baidu.com/s/1WmxrQX-pp8Wu1T_ga2vnKQ')



    def update_command(self,text):
        self.command_text.append(text)
        QApplication.processEvents()

    def _create(self):

        src_dir = self.src_edit.text()
        out_dir = self.export_edit.text()

        if src_dir and out_dir:
            self.update_parms()
            self.config['src_folder'] = src_dir
            # imgs_path_list= [os.path.join(src_dir,img) for img in os.listdir(src_dir)]
            depth_folder = os.path.join(out_dir,'depth')
            mesh_folder = os.path.join(out_dir,'mesh')
            video_folder = os.path.join(out_dir,'video')
            self.config['depth_folder'] = depth_folder
            self.config['mesh_folder'] = mesh_folder
            self.config['video_folder'] = video_folder

            os.makedirs(self.config['mesh_folder'], exist_ok=True)
            os.makedirs(self.config['video_folder'], exist_ok=True)
            os.makedirs(self.config['depth_folder'], exist_ok=True)

            # print(imgs_path_list)
            print('001')
            if self.config['offscreen_rendering'] is True:
                vispy.use(app='egl')
            # try:
            sample_list = get_MiDaS_samples(self.config['src_folder'], self.config['depth_folder'], self.config, self.config['specific'])
            # except Exception as get_MiDaS_samples_ERR:
            #     print('get_MiDaS_samples_ERR:',str(get_MiDaS_samples_ERR))
            normal_canvas, all_canvas = None, None
            if isinstance(self.config["gpu_ids"], int) and (self.config["gpu_ids"] >= 0):
                device = self.config["gpu_ids"]
            else:
                device = "cpu"
            device ='cuda'
            self.update_command(f"running on device {device}")
            print('002')
            for idx in tqdm(range(len(sample_list))):
                depth = None
                sample = sample_list[idx]
                self.command_text.append(f"Current Source ==>{sample['src_pair_name']}")
                mesh_fi = os.path.join(self.config['mesh_folder'], sample['src_pair_name'] + '.ply')
                # image = imageio.imread(sample['ref_img_fi'])
                image = cv2.imread(sample['ref_img_fi'],cv2.IMREAD_UNCHANGED)
                image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
                self.update_command(f"Running depth extraction at {time.time()}")
                if self.config['require_midas'] is True:
                    run_depth([sample['ref_img_fi']], self.config['src_folder'], self.config['depth_folder'],
                              self.config['MiDaS_model_ckpt'], MonoDepthNet, MiDaS_utils, target_w=640)
                if 'npy' in self.config['depth_format']:
                    self.config['output_h'], self.config['output_w'] = np.load(sample['depth_fi']).shape[:2]
                else:
                    # self.config['output_h'], self.config['output_w'] = imageio.imread(sample['depth_fi']).shape[:2]
                    self.config['output_h'], self.config['output_w'] = cv2.imread(sample['depth_fi'],cv2.IMREAD_UNCHANGED).shape[:2]
                if self.keep_len_check.isChecked():
                    self.config['output_h'], self.config['output_w'] = cv2.imread(sample['ref_img_fi'],
                                                                                  cv2.IMREAD_UNCHANGED).shape[:2]
                    self.config['longer_side_len'] = max(self.config['output_h'], self.config['output_w'])
                frac = self.config['longer_side_len'] / max(self.config['output_h'], self.config['output_w'])


                print('004')
                self.config['output_h'], self.config['output_w'] = int(self.config['output_h'] * frac), int(self.config['output_w'] * frac)
                self.config['original_h'], self.config['original_w'] = self.config['output_h'], self.config['output_w']
                if image.ndim == 2:
                    image = image[..., None].repeat(3, -1)
                if np.sum(np.abs(image[..., 0] - image[..., 1])) == 0 and np.sum(np.abs(image[..., 1] - image[..., 2])) == 0:
                    self.config['gray_image'] = True
                else:
                    self.config['gray_image'] = False
                image = cv2.resize(image, (self.config['output_w'], self.config['output_h']), interpolation=cv2.INTER_AREA)

                self.update_command(f"read_MiDaS_depth at {time.time()}")
                print('005')
                depth = read_MiDaS_depth(sample['depth_fi'], 3.0, self.config['output_h'], self.config['output_w'])
                mean_loc_depth = depth[depth.shape[0]//2, depth.shape[1]//2]
                print('006')
                if not(self.config['load_ply'] is True and os.path.exists(mesh_fi)):
                    self.update_command(f"sparse_bilateral_filtering at {time.time()}")
                    vis_photos, vis_depths = sparse_bilateral_filtering(depth.copy(), image.copy(), self.config, num_iter=self.config['sparse_iter'], spdb=False)
                    depth = vis_depths[-1]
                    model = None
                    torch.cuda.empty_cache()
                    self.update_command("Start Running 3D_Photo ...")
                    self.update_command(f"Loading edge model at {time.time()}")
                    depth_edge_model = Inpaint_Edge_Net(init_weights=True)
                    depth_edge_weight = torch.load(self.config['depth_edge_model_ckpt'],
                                                   map_location=torch.device(device))
                    depth_edge_model.load_state_dict(depth_edge_weight)
                    depth_edge_model = depth_edge_model.to(device)
                    depth_edge_model.eval()

                    self.update_command(f"Loading depth model at {time.time()}")
                    depth_feat_model = Inpaint_Depth_Net()
                    depth_feat_weight = torch.load(self.config['depth_feat_model_ckpt'],
                                                   map_location=torch.device(device))
                    depth_feat_model.load_state_dict(depth_feat_weight, strict=True)
                    depth_feat_model = depth_feat_model.to(device)
                    depth_feat_model.eval()
                    depth_feat_model = depth_feat_model.to(device)
                    self.update_command(f"Loading rgb model at {time.time()}")
                    rgb_model = Inpaint_Color_Net()
                    rgb_feat_weight = torch.load(self.config['rgb_feat_model_ckpt'],
                                                 map_location=torch.device(device))
                    rgb_model.load_state_dict(rgb_feat_weight)
                    rgb_model.eval()
                    rgb_model = rgb_model.to(device)
                    graph = None

                    self.update_command(f"Writing depth ply (and basically doing everything) at {time.time()}")
                    rt_info = write_ply(image,
                                        depth,
                                        sample['int_mtx'],
                                        mesh_fi,
                                        self.config,
                                        rgb_model,
                                        depth_edge_model,
                                        depth_edge_model,
                                        depth_feat_model,
                                        self)
                    self.update_command('write_ply completed')
                    if rt_info is False:
                        continue
                    rgb_model = None
                    color_feat_model = None
                    depth_edge_model = None
                    depth_feat_model = None
                    torch.cuda.empty_cache()
                    self.update_command('torch.cuda.empty_cache')
                if self.config['save_ply'] is True or self.config['load_ply'] is True:
                    verts, colors, faces, Height, Width, hFov, vFov = read_ply(mesh_fi)
                else:
                    verts, colors, faces, Height, Width, hFov, vFov = rt_info

                self.update_command(f"Making video at {time.time()}")
                videos_poses, video_basename = copy.deepcopy(sample['tgts_poses']), sample['tgt_name']
                self.update_command('deepcopy')
                top = (self.config.get('original_h') // 2 - sample['int_mtx'][1, 2] * self.config['output_h'])
                left = (self.config.get('original_w') // 2 - sample['int_mtx'][0, 2] * self.config['output_w'])
                down, right = top + self.config['output_h'], left + self.config['output_w']
                border = [int(xx) for xx in [top, down, left, right]]
                self.update_command('output_3d_photo start')
                normal_canvas, all_canvas = output_3d_photo(self,verts.copy(), colors.copy(), faces.copy(), copy.deepcopy(Height), copy.deepcopy(Width), copy.deepcopy(hFov), copy.deepcopy(vFov),
                                    copy.deepcopy(sample['tgt_pose']), sample['video_postfix'], copy.deepcopy(sample['ref_pose']), copy.deepcopy(self.config['video_folder']),
                                    image.copy(), copy.deepcopy(sample['int_mtx']), self.config, image,
                                    videos_poses, video_basename, self.config.get('original_h'), self.config.get('original_w'), border=border, depth=depth, normal_canvas=normal_canvas, all_canvas=all_canvas,
                                    mean_loc_depth=mean_loc_depth)

                self.update_command('output_3d_photo completed')

            self.update_command('Done !')



    def _help(self):
        QMessageBox.about(None, '帮助', '1.默认fps为30，总帧数为180帧，可以根据实际需求进行设置\n\n'
                                      '2.默认最长尺寸为960像素，勾上<保持原图大小>可以保持原输入图像大小\n\n'
                                      '3.图片格式暂时只支持uint8，像exr,tif等float32格式的暂不支持找了半天 \n'
                                      '  没解决，先搁置。\n\n'
                                      '5.主要的基本参数与高级图像处理参数已经区分\n\n'
                                      '6.给每个参数有所简单备注说明，鼠标放在参数名上可以查看\n\n'
                                      '7.支持多个图片生成，每次生成4个3D视频\n\n'
                                      '8.每张图片生成速度与电脑性能有关大概3分钟\n\n'
                                      '5.输出需要指定一个输出目录，输出的视频在该目录下的video文件夹中\n\n'
                                  )


if __name__ == '__main__':
    os.chdir(os.path.dirname(__file__))
    app = QApplication(sys.argv)
    p = PhotoInpainting()
    p.show()
    sys.exit(app.exec_())